package server

import (
	"context"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/samber/do/v2"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"golang.org/x/sync/errgroup"

	"gitee.com/monkeyPP/happy-mall/pkg/log"
	httpServer "gitee.com/monkeyPP/happy-mall/services/userservice/internal/infrastructure/http"
)

// TODO 需要启动 grpc 服务器

// Manager 服务器管理器
type Manager struct {
	httpServer *httpServer.ServerManager
	//grpcServer *grpcServer.GRPCServerManager
	injector do.Injector
}

// Config 服务器配置
type Config struct {
	HTTPPort int
	GRPCPort int
}

// NewServerManager 创建新的服务器管理器
func NewServerManager(i do.Injector) (*Manager, error) {
	// TODO: 这里应该通过依赖注入容器来管理，当前是临时实现
	//userRepo := repository.NewMockUserRepository()
	//userService := service.NewUserService(userRepo)
	//userApp := application.NewUserApp(userService)

	//// 创建 gRPC 服务器管理器
	//grpcConfig := &grpcServer.Config{
	//	Port:                  config.GRPCPort,
	//	EnableReflection:      true,            // 开发环境启用反射
	//	MaxReceiveMessageSize: 4 * 1024 * 1024, // 4MB
	//	MaxSendMessageSize:    4 * 1024 * 1024, // 4MB
	//}
	//grpcServerManager := grpcServer.NewGRPCServerManager(logger, grpcConfig)
	//
	//// 创建并注册用户服务
	//userServiceServer := grpcServices.NewUserServiceServer(userApp, logger)
	//grpcServerManager.RegisterService(userServiceServer)

	httpServerManager := do.MustInvoke[*httpServer.ServerManager](i)
	return &Manager{
		httpServer: httpServerManager,
		//grpcServer: grpcServerManager,
		injector: i,
	}, nil
}

// Start 启动所有服务器
func (sm *Manager) Start() error {
	log.Infow("starting user service servers", "http_port", viper.GetInt("port"))

	// 使用 errgroup 并发启动多个服务器
	g, ctx := errgroup.WithContext(context.Background())

	// 启动 HTTP 服务器
	g.Go(func() error {
		log.Infow("starting HTTP server")
		return sm.httpServer.Start()
	})

	// 启动 gRPC 服务器
	//g.Go(func() error {
	//	sm.logger.Info("starting gRPC server")
	//	return sm.grpcServer.Start()
	//})

	// 监听系统信号进行优雅关闭
	g.Go(func() error {
		return sm.handleShutdown(ctx)
	})

	// 等待所有 goroutine 完成
	return g.Wait()
}

// handleShutdown 处理优雅关闭
func (sm *Manager) handleShutdown(ctx context.Context) error {
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	select {
	case sig := <-quit:
		log.C(ctx).Infow("received shutdown signal", "signal", sig.String())
	case <-ctx.Done():
		return nil
	}

	// 开始优雅关闭
	log.C(ctx).Infow("shutting down servers...")

	// 创建关闭上下文，给服务器 30 秒时间优雅关闭
	shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 关闭 gRPC 服务器
	//sm.grpcServer.Stop()

	// 关闭 HTTP 服务器
	if err := sm.httpServer.Stop(shutdownCtx); err != nil {
		log.C(shutdownCtx).Errorw("HTTP server shutdown failed", zap.Error(err))
		return err
	}

	log.C(ctx).Infow("all servers stopped gracefully")
	return nil
}

// Stop 手动停止所有服务器
func (sm *Manager) Stop() error {
	log.Infow("manually stopping servers...")

	shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 关闭 gRPC 服务器
	//sm.grpcServer.Stop()

	// 关闭 HTTP 服务器
	if err := sm.httpServer.Stop(shutdownCtx); err != nil {
		log.C(shutdownCtx).Errorw("HTTP server shutdown failed", "err", err)
		return err
	}

	log.C(shutdownCtx).Infow("all servers stopped")
	return nil
}
